package com.xdap.wecom.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description:
 * @author: shangsheng.li
 * @since: 2022/6/21 2:23 下午
 * @history: 1.2022/6/21 created by shangsheng.li
 */
@Slf4j
@Component
public class HttpRequestClient {

    private String domain;
    private Map<String, String> requestHeaders;

    private Charset encoding;

    public HttpRequestClient() {
        this.init();
    }

    public void addHeader(String name, String value) {
        requestHeaders.put(name, value);
    }

    public void setRequestHeaders(Map<String, String> requestHeaders) {
        this.requestHeaders = requestHeaders;
    }

    public void utf8() {
        this.encoding = StandardCharsets.UTF_8;
    }

    private void init() {
        this.requestHeaders = new HashMap<>();
    }

    public HttpRequestClient(String domain) {
        this.domain = domain;
        this.init();
    }

    public String get(String uri) {
        return get(uri, Collections.EMPTY_MAP);
    }

    /**
     * 发送get请求
     *
     * @param uri           子路径（如果http或者https开头则使用全路径）
     * @param requestParams 路径参数
     * @return
     */
    public String get(String uri, Map<String, String> requestParams) {
        String url = this.getFullURL(uri, requestParams);
        log.info("请求地址+参数为：{}",url);
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        for (String key : requestHeaders.keySet()) {
            headers.add(key, requestHeaders.get(key));
        }
        HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class, requestParams);
        return response.getBody();
    }

    /**
     * 发送post请求
     *
     * @param uri
     * @param data
     * @param requestParams
     * @return
     */
    public String post(String uri, Object data, Map<String, String> requestParams) {
        return execute(HttpMethod.POST, uri, data, requestParams);
    }

    /**
     * 发送put请求
     *
     * @param uri
     * @param data
     * @param requestParams
     * @return
     */
    public String put(String uri, Object data, Map<String, String> requestParams) {
        return execute(HttpMethod.PUT, uri, data, requestParams);
    }

    private String execute(HttpMethod method, String uri, Object data, Map<String, String> requestParams) {
        String url = this.getFullURL(uri, requestParams);
        RestTemplate restTemplate = this.createRestTemplate();
        HttpHeaders headers = new HttpHeaders();
        for (String key : requestHeaders.keySet()) {
            headers.add(key, requestHeaders.get(key));
        }
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> requestEntity = new HttpEntity<>(data == null ? null : JSON.toJSONString(data), headers);
        log.info("url:{}", url);
        log.info("method:{}", method);
        log.info("requestEntity:{}", JSONArray.toJSONString(requestEntity));
        ResponseEntity<String> response = restTemplate.exchange(url, method, requestEntity, String.class);
        log.info("response:{}", JSONArray.toJSONString(response));
        return response.getBody();
    }

    /**
     * 创建restTemplate
     *
     * @return
     */
    private RestTemplate createRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        if (this.encoding != null) {
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(this.encoding));
        }
        return restTemplate;
    }

    /**
     * 发送post请求
     *
     * @param uri  子路径（如果http或者https开头则使用全路径）
     * @param data post的数据，会自动转为json进行发送
     * @return
     */
    public String post(String uri, Object data) {
        return post(uri, data, null);
    }

    /**
     * 获取完整接口路径
     *
     * @param uri
     * @return
     */
    public String getFullURL(String uri, Map<String, String> requestParams) {

        String url = uri.replaceAll("([^:])/[/]+", "$1/");
        if (requestParams != null && !requestParams.isEmpty()) {
            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
            for (String k : requestParams.keySet()) {
                uriBuilder.queryParam(k, requestParams.get(k));
            }
            url = uriBuilder.build().encode().toString();
        }
        if (this.domain == null || uri.startsWith("http://") || uri.startsWith("https://")) {
            return url;
        }
        url = domain + "/" + url;
        return url;
    }
}
